package com.gin.kotlin.no_gay_alliance.worker

import android.content.Context
import androidx.work.BackoffPolicy
import androidx.work.Constraints
import androidx.work.Data
import androidx.work.NetworkType
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkContinuation
import androidx.work.WorkManager
import androidx.work.WorkRequest
import androidx.work.Worker
import androidx.work.WorkerParameters
import com.gin.kotlin.no_gay_alliance.app.App
import com.gin.kotlin.no_gay_alliance.argument.UserCenterArgument
import com.gin.kotlin.no_gay_alliance.provider.ngaphp.UserInfoProvider
import java.util.concurrent.TimeUnit

class UserIpLocationWorker(context: Context, workerParams: WorkerParameters) : Worker(context, workerParams) {
    override fun doWork(): Result {
        val userId = inputData.getLong(KEY_USER_ID, 0).takeIf { it > 0 } ?: return Result.failure()

        val params = UserCenterArgument(userId = userId)
        val provider = UserInfoProvider.getInstance()
        try {
            provider.execute(params)
        } catch (ex: Exception) {
            try {
                provider.execute(params.copy(html = true))
            } catch (e: Exception) {
                e.printStackTrace()
                return Result.failure()
            }
        }

        return Result.success()
    }

    companion object {
        private const val KEY_USER_ID = "user_id"

        @JvmStatic
        fun buildRequest(userId: Long) = OneTimeWorkRequest.Builder(UserIpLocationWorker::class.java)
            // 执行参数
            .setInputData(Data.Builder().putLong(KEY_USER_ID, userId).build())
            // 任务限制：必须联网
            .setConstraints(Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build())
            .setInitialDelay(10, TimeUnit.SECONDS)
            // 重试策略
            .setBackoffCriteria(BackoffPolicy.LINEAR, WorkRequest.MIN_BACKOFF_MILLIS, TimeUnit.MILLISECONDS)
            .build()

        /**
         * 开始一个系列任务
         * @param userId List<Long>
         */
        @JvmStatic
        fun start(userId: List<Long>) {
            if (userId.isEmpty()) return
            val manager = WorkManager.getInstance(App.INSTANCE)
            var workContinuation: WorkContinuation? = null
            val requests = userId.map { buildRequest(it) }

            requests.forEach {
                workContinuation = if (workContinuation == null)
                    manager.beginWith(it)
                else
                    workContinuation!!.then(it)
            }
            workContinuation!!.enqueue()
        }
    }
}